from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
import cgi
import re
import math
from django.utils import simplejson

class User(db.Model):
    user_id = db.IntegerProperty(required=True)
    username = db.StringProperty(multiline=True)
    dna = db.TextProperty(required=True)
    date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp.RequestHandler):
    def get(self):
        self.response.out.write(cgi.escape(self.request.get('content')))

class SaveTags(webapp.RequestHandler):
    def post(self):
        
        result = simplejson.loads(self.request.body)
        users = result['user']
        for user in users:
            id = long(user['id'])
            self.response.out.write(user['id'])
            dbUsers = db.GqlQuery("SELECT * FROM User WHERE user_id = :1",id)
            if dbUsers.get() != None:
                dbUser = dbUsers.get()
                dbUser.username = user['username']
                if 'dna' in user:
                    self.response.out.write(':'+user['dna'])
                    dbUser.dna = user['dna']
                dbUser.put()
            else:
                greeting = User(user_id = 0, dna = 'default')
                greeting.user_id = id
                greeting.username = user['username']
                if 'dna' in user:
                    self.response.out.write(':'+user['dna'])
                    greeting.dna = user['dna']
                greeting.put()
            self.response.out.write('\n')
        dbUsers = db.GqlQuery("SELECT * FROM User WHERE username = :1",'Kira')
        if dbUsers.get() != None:
            self.response.out.write('Found')

        self.response.out.write(cgi.escape(self.request.body))

class Guestbook(webapp.RequestHandler):
    def post(self):
        
        def chiSquare(words, wordsOfAllRaw, vocabOfAllRaw):

            textLength = len(words)
            allTextLength = len(wordsOfAllRaw)
            chiSquareList = []
            counter = 0
    
            for v in vocabOfAllRaw:
                num = words.count(v)
                allNum = wordsOfAllRaw.count(v)
                w = num
                x = textLength - num
                y = allNum - num
                z = allTextLength - w - x - y
                counter += 1
                chiSquare = ((w+x+y+z)*pow((w*z-x*y),2))/float((w+x)*(w+y)*(x+z)*(y+z))
                ##print chiSquare
                chiSquareList.append(chiSquare)
            return chiSquareList
        
        def chiSquareToFeatures(chiSquareList):
            chiSquareListTemp = []
            chiSquareRankingList = []
            features = []
            chiSquareListTemp += chiSquareList
            chiSquareRankingList += chiSquareList
            chiSquareRankingList.sort()
            chiSquareRankingList.reverse()
            counter = 0
            for w in chiSquareRankingList:
                ##features.append(chiSquareListTemp.index(w))
                #chiSquareListTemp[chiSquareListTemp.index(w)] = 0
                features.append(counter)
                counter += 1
            features.sort()
            ##print features
            return features
        
        def featuresToRepre(words, features, vocabOfAllRaw):
            vocab = [vocabOfAllRaw[i] for i in features]
            repre = []
            for v in vocab:
                repre.append(words.count(v))
            return repre
                
        # method for caculating the Cosine Similarity
        def sim(repreOfInput,repreOfClass):
            upSum = 0
            inputPowSum = 0
            classPowSum = 0
            for i in xrange(0,len(repreOfInput),1):
                upSum += repreOfInput[i]*repreOfClass[i]
            for i in xrange(0,len(repreOfInput),1):
                inputPowSum += pow(repreOfInput[i],2)
                inputPSS = math.sqrt(inputPowSum)
            for i in xrange(0,len(repreOfInput),1):
                classPowSum += pow(repreOfClass[i],2)
            classPSS = math.sqrt(classPowSum)
            similarity = upSum/float(inputPSS*classPSS)
            ##print similarity
            return similarity
        
        # accumulate the score
        def accumulate(repreOfInput,repres):
            score = 0
            for i in xrange(0,len(repres),1):
                if any(repreOfInput) and any(repres[i]):
                    similarity = sim(repreOfInput, repres[i])
                    # radius adjustment
                    if similarity >= 0.35:
                        # weighted k-NN
                        score += similarity
                        #score += 1
                ##else:
                    ##print 'ZeroDivisionError'
            return score
        
        result = simplejson.loads(self.request.body)
        user_id = long(result['id'])
        ##self.response.out.write(user_id)
        ##self.response.out.write('\n')
        dbUsers = db.GqlQuery("SELECT * FROM User")
        if dbUsers.get() != None:
            ##self.response.out.write('Found')
            tagLists0 = [re.split('\W+', dbUser.dna) for dbUser in dbUsers]
            ##self.response.out.write(tagLists0)
            ##self.response.out.write('\n')
            tagListAll0 = []
            for tagList0 in tagLists0:
                tagListAll0 += tagList0
            ##self.response.out.write(tagListAll0)
            ##self.response.out.write('\n')
            vocabOfAllRaw0 = sorted(set(tagListAll0))
            ##self.response.out.write(vocabOfAllRaw0)
            ##self.response.out.write('\n')
            chiSquareLists0 = [chiSquare(tagList0, tagListAll0, vocabOfAllRaw0) for tagList0 in tagLists0]
            ##self.response.out.write(chiSquareLists0)
            ##self.response.out.write('\n')
            chiSquareListOfAll0 = []
            for i in xrange(0,len(vocabOfAllRaw0),1):
                for chiSquareList0 in chiSquareLists0:
                    acc = 0
                    acc += chiSquareList0[i]
                chiSquareListOfAll0.append(acc)
            ##self.response.out.write(chiSquareListOfAll0)
            ##self.response.out.write('\n')
            featuresOfAll0 = chiSquareToFeatures(chiSquareListOfAll0)
            ##self.response.out.write(featuresOfAll0)
            ##self.response.out.write('\n')
            repreOfInputAll0 = [featuresToRepre(tagList0, featuresOfAll0, vocabOfAllRaw0) for tagList0 in tagLists0]
            ##self.response.out.write(repreOfInputAll0)
            ##self.response.out.write('\n')
            represOfGroupAll0 = [[repreOfInput0] for repreOfInput0 in repreOfInputAll0]
            ##self.response.out.write(represOfGroupAll0)
            ##self.response.out.write('\n')
            ##scoreOfAll = map(accumulate, repreOfInputAll0, represOfGroupAll0)
            scoreOfAll = []
            counter = 0
            for represOfGroup0 in represOfGroupAll0:
                if counter == user_id-1:
                    ##self.response.out.write(user_id)
                    ##self.response.out.write('\n')
                    scoreOfAll.append(0)
                else:
                    scoreOfAll.append(accumulate(repreOfInputAll0[user_id-1],represOfGroup0))
                counter += 1
            ##self.response.out.write(scoreOfAll)
            ##self.response.out.write('\n')
            match_user_list = [(scoreOfAll.index(score) + 1) for score in scoreOfAll if score > 0.6]
            self.response.out.write(match_user_list)
            ##self.response.out.write('\n')
            maxScore0 = max(scoreOfAll)
            match_user_id = scoreOfAll.index(maxScore0) + 1
            ##self.response.out.write(str(match_user_id))
            ##self.response.out.write('\n')
                       
        ##self.response.out.write(cgi.escape(self.request.body))
        ##self.response.out.write(' ')

application = webapp.WSGIApplication(
                                     [('/', MainPage),
                                      ('/sign', Guestbook),
                                      ('/save_tags', SaveTags)],
                                     debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()